package com.arrogames.blondbattle.game.movement 
{
	import ash.core.Engine;
	import ash.core.NodeList;
	import ash.core.System;
	import com.arrogames.blondbattle.game.movement.Motion;
	import com.arrogames.blondbattle.game.purchases.NewUnit;
	import com.arrogames.blondbattle.game.movement.Position;
	import com.arrogames.blondbattle.game.movement.Spawner;
	import com.arrogames.blondbattle.game.combat.Faction;
	import com.arrogames.blondbattle.game.purchases.Costs;
	import com.arrogames.blondbattle.game.purchases.NewUnitNode;
	import com.arrogames.blondbattle.game.movement.SpawnerNode;
	import org.as3commons.logging.api.getLogger;
	import org.as3commons.logging.api.ILogger;
	
	/**
	 * ...
	 * @author Robin van den Bogaard
	 */
	public class SpawnSystem extends System {
		
		private static const logger:ILogger = getLogger(SpawnSystem);
		
		private var spawns:NodeList;
		private var newUnits:NodeList;
		
		public function SpawnSystem() {
			super();
		}
		
		override public function addToEngine(engine:Engine):void {
			super.addToEngine(engine);
			
			spawns = engine.getNodeList(SpawnerNode);
			newUnits = engine.getNodeList(NewUnitNode);
			
		}
		
		override public function removeFromEngine(engine:Engine):void {
			super.removeFromEngine(engine);
			spawns.nodeAdded.removeAll();
			spawns = null;
			newUnits = null;
		}
		
		override public function update(time:Number):void {
			super.update(time);
			var node:NewUnitNode;
			for (node = newUnits.head; node ; node = node.next) {
				attemptToSpawn(node);
			}
		}
		
		private function attemptToSpawn(node:NewUnitNode):void {
			var spawnNode:SpawnerNode = findSpawnFor(node);
			if (spawnNode != null) {
				spawnNewUnitAt(node,spawnNode);
			} else {
				logger.debug("No spawner found for unit with faction '"+node.faction.name+"'");
			}
		}
		
		private function spawnNewUnitAt(unit:NewUnitNode, spawn:SpawnerNode):void {
			var costs:Costs = unit.entity.get(Costs);
			logger.debug("Spawning new unit with for faction '" + unit.faction.name+"' costs: " + costs.value);
			unit.entity.add(new Position(spawn.position.position.x, spawn.position.position.y, spawn.position.rotation));
			unit.entity.add(getDirection(spawn.spawn.originalSpawn, unit.marker.unitDefinition.speed));
			unit.entity.remove(NewUnit);
		}
		
		private function getDirection(originalSpawn:String, speed:Number): Motion {
			var actualSpeed:Number = speed;
			if (originalSpawn == Faction.COMPUTER) {
				actualSpeed = -speed;
			} 
			return new Motion (actualSpeed, 0, 0, 0);
		}
		
		private function findSpawnFor(unitNode:NewUnitNode):SpawnerNode {
			var result:SpawnerNode = null;
			var node:SpawnerNode;
			for (node = spawns.head; node && result == null; node = node.next) {
				if (node.faction.name == unitNode.faction.name) {
					result = node;
				}
			}
			return result;
		}
		
	}

}